home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Kant Generator Pro 1.2 / src / Shell ƒ / main.c < prev    next >
C/C++ Source or Header  |  1995-02-13  |  10KB  |  365 lines

  1. #define USE_MERCUTIO        0
  2.  
  3. #include "main.h"
  4. #include "drag utilities.h"
  5. #include "apple events.h"
  6. #include "integrity.h"
  7. #include "menus.h"
  8. #include "prefs.h"
  9. #include "environment.h"
  10. #include "error.h"
  11. #include "print meat.h"
  12. #include "graphics.h"
  13. #include "graphics dispatch.h"
  14. #include "window layer.h"
  15. #include "program globals.h"
  16. #include "kant.h"
  17. #include <AppleEvents.h>
  18. #include <EPPC.h>
  19. #include <CursorCtl.h>
  20. #if USE_MERCUTIO
  21. #include "Mercutio API.h"
  22. #endif
  23.  
  24. static    short        gTheCurrentModifiers;
  25.  
  26. void main(void)
  27. {
  28.     Boolean            programIntegrityVerified;
  29.     Boolean            programIntegritySet;
  30.     
  31.     /* do integrity check before anything else; see integrity.c for details */
  32.     programIntegrityVerified=DoIntegrityCheck(&programIntegritySet);
  33.     
  34.     /* standard program initialization stuff */
  35.     MaxApplZone();    
  36.     InitGraf(&qd.thePort);
  37.     InitFonts();
  38.     FlushEvents(everyEvent, 0);
  39.     InitWindows();
  40.     InitMenus();
  41.     TEInit();
  42.     InitDialogs(0L);
  43.     InitCursor();
  44.     InitCursorCtl(0L);
  45.     GetDateTime((unsigned long*)&qd.randSeed);
  46.     
  47.     InitTheDragManager();
  48.     InitTheWindowLayer();
  49.     
  50.     if (!InitTheEnvironment())            /* gestalt checks and variable initialization */
  51.         HandleError(kSystemTooOld, TRUE, TRUE);        /* less than system 7.0 */
  52.     
  53.     if (!programIntegrityVerified)    /* integrity check failed */
  54.         HandleError(kProgramIntegrityNotVerified, TRUE, FALSE);
  55.     
  56.     if (programIntegritySet)    /* integrity check freshly installed */
  57.         HandleError(kProgramIntegritySet, FALSE, TRUE);
  58.     
  59.     PrefsError(PreferencesInit());    /* get prefs (create if necessary) */
  60.     
  61.     if (!InitTheMenus())        /* get menus from .rsrc and draw menu bar */
  62.         HandleError(kProgramIntegrityNotVerified, TRUE, FALSE);
  63.         
  64.     InitThePrinting();
  65.     
  66.     InitTheProgram();
  67.     
  68.     EventLoop();                    /* where it all happens (see below) */
  69.     
  70.     ShutDownEnvironment(TRUE);        /* where it all ends (see below) */
  71.     
  72.     ExitToShell();
  73. }
  74.  
  75. void EventLoop(void)
  76. {
  77.     while (!gDone)    /* gDone set by choosing "Quit" menu item or by "quit" apple event */
  78.         HandleSingleEvent(TRUE);
  79. }
  80.  
  81. Boolean HandleSingleEvent(Boolean allowContextSwitching)
  82. {
  83.     EventRecord        theEvent;
  84.     WindowPtr        front;
  85.     
  86.     if (!gCustomCursor)
  87.         SetCursor(&qd.arrow);
  88.     HiliteMenu(0);            /* normalize menubar */
  89.     
  90.     gFrontWindowIndex=-1;
  91.     front=FrontWindow();
  92.     if (front!=0L)    /* if there's a front window, see if it's one of ours */
  93.     {
  94.         SetPort(front);
  95.         gFrontWindowIndex=GetWindowIndex(front);
  96.     }
  97.         
  98.     /* get an event from the queue */
  99.     WaitNextEvent(everyEvent, &theEvent, gIsInBackground ? gBackgroundWaitTime : gForegroundWaitTime, 0L);
  100.     gTheCurrentModifiers=theEvent.modifiers;
  101.     
  102.     DispatchEvents(theEvent, allowContextSwitching);    /* handle the event we just got */
  103.     
  104.     return (theEvent.what!=nullEvent);
  105. }
  106.  
  107. short GetTheModifiers(void)
  108. {
  109.     return gTheCurrentModifiers;
  110. }
  111.  
  112. void DispatchEvents(EventRecord theEvent, Boolean allowContextSwitching)
  113. {
  114.     Point            thisPoint;
  115.     short            index;
  116.     WindowPtr        theWindow;
  117.     unsigned char    theChar;
  118.     long            dummy;
  119.     
  120.     index=gFrontWindowIndex;
  121.     
  122.     switch (theEvent.what)
  123.     {
  124.         case nullEvent:    /* ain't nuthin' happenin' */
  125.             if (gKludgeIter<3)
  126.             {
  127.                 gKludgeIter++;
  128.             }
  129.             else
  130.             {
  131.                 if (gNeedToOpenWindow)
  132.                 {
  133.                     OpenTheIndWindow(kMainWindow);
  134.                     gNeedToOpenWindow=FALSE;
  135.                 }
  136.             }
  137.             
  138.             thisPoint=theEvent.where;
  139.             GlobalToLocal(&thisPoint);
  140.             theWindow=FrontWindow();
  141.             if (WindowIsFloat(theWindow))
  142.             {
  143.                 if (IdleWindowDispatch(index, thisPoint)==kPassThrough)
  144.                 {
  145.                     if ((theWindow=GetFrontDocumentWindow())!=0L)
  146.                     {
  147.                         index=GetWindowIndex(theWindow);
  148.                         SetPort(theWindow);
  149.                         thisPoint=theEvent.where;
  150.                         GlobalToLocal(&thisPoint);
  151.                         IdleWindowDispatch(index, thisPoint);
  152.                     }
  153.                 }
  154.             }
  155.             else
  156.             {
  157.                 IdleWindowDispatch(index, thisPoint);
  158.             }
  159.             break;
  160.         case mouseDown:    /* mouse button pressed */
  161.             HandleMouseDown(theEvent, allowContextSwitching);    /* see below for mousedown handling */
  162.             break;
  163.         case keyDown:    /* key pressed */
  164.         case autoKey:    /* key help down */
  165.             theChar=(char)(theEvent.message & charCodeMask);
  166.             if (theEvent.modifiers & cmdKey)
  167.             {
  168.                 AdjustMenus();
  169. #if USE_MERCUTIO
  170.                 dummy=PowerMenuKey(theEvent.message, theEvent.modifiers, gBuildMenu);
  171.                 if (dummy==0L)
  172. #endif
  173.                     dummy=MenuKey(theChar);
  174.                 HandleMenu(dummy);
  175.             }
  176.             else
  177.             {
  178.                 theWindow=FrontWindow();
  179.                 if (WindowIsFloat(theWindow))
  180.                 {
  181.                     if (KeyDownDispatch(index, theChar)==kPassThrough)
  182.                     {
  183.                         if ((theWindow=GetFrontDocumentWindow())!=0L)
  184.                         {
  185.                             index=GetWindowIndex(theWindow);
  186.                             KeyDownDispatch(index, theChar);
  187.                         }
  188.                     }
  189.                 }
  190.                 else
  191.                 {
  192.                     KeyDownDispatch(index, theChar);
  193.                 }
  194.                 ResetHiliteRgn(theWindow);
  195.             }
  196.             break;
  197.         case diskEvt:    /* disk insert */
  198.             if (HiWord(theEvent.message)!=noErr)    /* bad disk inserted */
  199.             {
  200.                 DILoad();    /* load disk initialization package */
  201.                 SetPt(&thisPoint, 120, 120);
  202.                 DIBadMount(thisPoint, theEvent.message);    /* give format? dialog */
  203.                 DIUnload();    /* unload 'cuz we certainly don't need it */
  204.             }
  205.             break;
  206.         case updateEvt:    /* window update */
  207.             theWindow=(WindowPtr)theEvent.message;    /* which window? */
  208.             BeginUpdate(theWindow);        /* means: "OK, we're dealing with this now" */
  209.             UpdateTheWindow(theWindow);
  210.             EndUpdate(theWindow);        /* means: "OK, we're done updating now" */
  211.             break;
  212.         case activateEvt:    /* window activate or deactivate */
  213.             if (gIgnoreNextActivateEvent)
  214.                 gIgnoreNextActivateEvent=FALSE;
  215.             else
  216.             {
  217.                 index=GetWindowIndex((WindowPtr)theEvent.message);
  218.                 if ((theEvent.modifiers & activeFlag)!=0)
  219.                     ActivateWindowDispatch(index);
  220.                 else
  221.                     DeactivateWindowDispatch(index);
  222.             }
  223.             break;
  224.         case osEvt:            /* suspend or resume program execution (switch in/out) */
  225.             if (((theEvent.message>>24)&0x0FF)==suspendResumeMessage)
  226.             {
  227.                 /* keep track of whether we're in the background or foreground */
  228.                 gIsInBackground=((theEvent.message&resumeFlag)==0);
  229.                 
  230.                 if (gIsInBackground)
  231.                     DeactivateWindowDispatch(index);
  232.                 else
  233.                     ActivateWindowDispatch(index);
  234.                 
  235.                 /* if we just came into the foreground and we have a pending error,
  236.                    now's the time to display it */
  237.                 if ((!gIsInBackground) && (gPendingErrorRec.resultCode!=allsWell))
  238.                 {
  239.                     if (gHasNotificationManager)
  240.                         NMRemove(&gPendingErrorRec.notificationRec);        /* remove notification request */
  241.                     HandleError(gPendingErrorRec.resultCode, gPendingErrorRec.isFatal,
  242.                         gPendingErrorRec.isSmall);    /* display alert, see error.c */
  243.                     gPendingErrorRec.resultCode=allsWell;        /* ...now it is */
  244.                 }
  245.                 
  246.                 if (!gIsInBackground)
  247.                     RebuildModulesMenu();
  248.             }
  249.             break;
  250.         case kHighLevelEvent:    /* apple event */
  251.             AEProcessAppleEvent(&theEvent);        /* see apple events.c */
  252.             break;
  253.     }
  254. }
  255.  
  256. void HandleMouseDown(EventRecord theEvent, Boolean allowContextSwitching)
  257. {
  258.     WindowPtr        theWindow;
  259.     short            windowCode;
  260.     long            windSize;
  261.     Rect            sizeRect;
  262.     short            index;
  263.     Point            theLocalPoint;
  264.     
  265.     windowCode=FindWindow(theEvent.where, &theWindow);    /* which window? */
  266.     index=GetWindowIndex(theWindow);
  267.     
  268.     switch (windowCode)
  269.     {
  270.         case inMenuBar:        /* in menu bar; let system take over */
  271.             AdjustMenus();
  272.             HandleMenu(MenuSelect(theEvent.where));
  273.             break;
  274.         case inContent:        /* in window content */
  275.             if (!DragInWindow(theWindow, &theEvent))
  276.             {
  277.                 if (!MySelectWindow(theWindow))        /* didn't need to change front windows */
  278.                 {
  279.                     theLocalPoint=theEvent.where;
  280.                     SetPort(theWindow);
  281.                     GlobalToLocal(&theLocalPoint);
  282.                     MouseDownDispatch(index, theLocalPoint);
  283.                 }
  284.             }
  285.             ResetHiliteRgn(theWindow);
  286.             break;
  287.         case inSysWindow:    /* in system window (desk accessory) */
  288.             if (allowContextSwitching)
  289.                 SystemClick(&theEvent, theWindow);    /* let the system deal with it */
  290.             break;
  291.         case inDrag:        /* in drag _region_, that is */
  292.             /* the accepted way to draw a window */
  293.             DragWindow(theWindow, theEvent.where, &((**GetGrayRgn()).rgnBBox));
  294.             /* update window bounds in window data struct */
  295.             SetWindowBounds(theWindow,
  296.                 (*(((WindowPeek)theWindow)->contRgn))->rgnBBox);
  297.             theLocalPoint.v=GetWindowBounds(theWindow).top;
  298.             theLocalPoint.h=GetWindowBounds(theWindow).left;
  299.             SetWindowTopLeft(theWindow, theLocalPoint);
  300.             MySelectWindow(theWindow);
  301.             break;
  302.         case inGoAway:        /* close box */
  303.             /* the accepted way to track a close box attempt */
  304.             if (TrackGoAway(theWindow, theEvent.where))
  305.                 DoTheCloseThing((WindowPeek)theWindow);        /* see menus.c */
  306.             break;
  307.         case inGrow:        /* grow box */
  308.             /* the accepted way to grow a window */
  309.             if (GetGrowSizeDispatch(index, &sizeRect)==kFailure)
  310.                 sizeRect=qd.screenBits.bounds;
  311.             
  312.             windSize=GrowWindow(theWindow, theEvent.where, &sizeRect);
  313.             if (windSize!=0)
  314.             {
  315.                 SizeWindow(theWindow, LoWord(windSize), HiWord(windSize), TRUE);
  316.                 EraseRect(&(theWindow->portRect));
  317.                 InvalRect(&(theWindow->portRect));
  318.                 
  319.                 SetWindowBounds(theWindow,
  320.                     (*(((WindowPeek)theWindow)->contRgn))->rgnBBox);
  321.                 SetWindowWidth(theWindow, theWindow->portRect.right-theWindow->portRect.left);
  322.                 SetWindowHeight(theWindow, theWindow->portRect.bottom-theWindow->portRect.top);
  323.                 
  324.                 theLocalPoint.v=GetWindowBounds(theWindow).top;
  325.                 theLocalPoint.h=GetWindowBounds(theWindow).left;
  326.                 SetWindowTopLeft(theWindow, theLocalPoint);
  327.                 GrowWindowDispatch(index);
  328.                 
  329.                 ResetHiliteRgn(theWindow);
  330.             }
  331.             break;
  332.         case inZoomIn:        /* zoom box */
  333.         case inZoomOut:
  334.             /* the accepted way to track a zoom attempt */
  335.             if (TrackBox(theWindow, theEvent.where, windowCode))
  336.             {
  337.                 ZoomWindow(theWindow, windowCode, FALSE);
  338.                 EraseRect(&(theWindow->portRect));
  339.                 InvalRect(&(theWindow->portRect));
  340.                 
  341.                 SetWindowWidth(theWindow, theWindow->portRect.right-theWindow->portRect.left);
  342.                 SetWindowHeight(theWindow, theWindow->portRect.bottom-theWindow->portRect.top);
  343.                 SetWindowBounds(theWindow,
  344.                     (*(((WindowPeek)theWindow)->contRgn))->rgnBBox);
  345.                 theLocalPoint.v=GetWindowBounds(theWindow).top;
  346.                 theLocalPoint.h=GetWindowBounds(theWindow).left;
  347.                 SetWindowTopLeft(theWindow, theLocalPoint);
  348.                 ZoomWindowDispatch(index);
  349.                 ResetHiliteRgn(theWindow);
  350.             }
  351.             break;
  352.     }
  353. }
  354.  
  355. void ShutDownEnvironment(Boolean fullShutdown)
  356. {
  357.     SaveThePrefs();
  358.     if (fullShutdown)
  359.     {
  360.         ShutDownTheProgram();        /* program-specific cleanup */
  361.         ShutDownTheWindowLayer();    /* do shutdown dispatch for all windows we've used */
  362.         ShutDownTheMenus();            /* release menu resources */
  363.     }
  364. }
  365.